package edu.hubu.model;

import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import net.moon.jpa.model.BaseEntity;
import org.hibernate.annotations.GenericGenerator;
import org.hibernate.annotations.SQLDelete;
import org.hibernate.annotations.Where;

import javax.persistence.*;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;

/**
 * @author moonlan
 * @date 2020/10/18 上午11:26
 */
@Entity
@Table(name = "role")
//逻辑删除注解，删除sql变成了update
@SQLDelete(sql = "update role set role_is_deleted = true where role_id = ?")
//where条件带上了逻辑删除条件
@Where(clause = "role_is_deleted = false")
@ApiModel("角色")
@JsonIgnoreProperties(value = {"hibernateLazyInitializer", "handler", "fieldHandler"})
public class Role extends BaseEntity implements Serializable {

    public Role(String roleName) {
        this.roleName = roleName;
    }

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO, generator = "snowflakeId")
    @GenericGenerator(name = "snowflakeId", strategy = "edu.hubu.commons.SnowflakeId",
                      parameters = {@org.hibernate.annotations.Parameter(name = "prefix", value = "ROLE")})
    @Column(name = "role_id")
    @ApiModelProperty(value = "角色Id", position = 1)
    private String roleId;

    @Column(name = "role_name")
    @ApiModelProperty(value = "角色名", position = 2)
    private String roleName;

    @Column(name = "role_is_forbidden")
    @ApiModelProperty(value = "角色是否被禁止", position = 3)
    private boolean roleIsForbidden = false;

    @Column(name = "role_is_deleted")
    @ApiModelProperty(value = "角色是否被删除", position = 4)
    private boolean roleIsDeleted = false;

    @OneToMany(mappedBy = "role", fetch = FetchType.LAZY)
    @ApiModelProperty(hidden = true)
    @JsonIgnore
    private List<User> users = new ArrayList<>();

    @OneToMany(mappedBy = "role", fetch = FetchType.LAZY)
    @ApiModelProperty(hidden = true)
    @JsonIgnore
    private List<Student> students = new ArrayList<>();

    @OneToMany(mappedBy = "role", fetch = FetchType.LAZY)
    @ApiModelProperty(hidden = true)
    @JsonIgnore
    private List<Teacher> teachers = new ArrayList<>();

    @ManyToMany(targetEntity = Permission.class, fetch = FetchType.LAZY, cascade = CascadeType.REFRESH)
    @JoinTable(name = "role_permission",
               joinColumns = {@JoinColumn(name = "role_permission_role_id", referencedColumnName = "role_id")},
               inverseJoinColumns = @JoinColumn(name = "role_permission_permission_id",
                                                referencedColumnName = "permission_id"))
    @ApiModelProperty(hidden = true)
    private List<Permission> permissions = new ArrayList<>();

    public List<Student> getStudents() {
        return students;
    }

    public Role setStudents(List<Student> students) {
        this.students = students;
        return this;
    }

    public List<Teacher> getTeachers() {
        return teachers;
    }

    public Role setTeachers(List<Teacher> teachers) {
        this.teachers = teachers;
        return this;
    }

    public Role(String roleId, String roleName, boolean roleIsForbidden, boolean roleIsDeleted, List<User> users, List<Permission> permissions) {
        this.roleId = roleId;
        this.roleName = roleName;
        this.roleIsForbidden = roleIsForbidden;
        this.roleIsDeleted = roleIsDeleted;
        this.users = users;
        this.permissions = permissions;
    }

    public Role() {
    }

    public static RoleBuilder builder() {
        return new RoleBuilder();
    }

    public String getRoleId() {
        return this.roleId;
    }

    public String getRoleName() {
        return this.roleName;
    }

    public boolean isRoleIsForbidden() {
        return this.roleIsForbidden;
    }

    public boolean isRoleIsDeleted() {
        return this.roleIsDeleted;
    }

    public List<User> getUsers() {
        return this.users;
    }

    public List<Permission> getPermissions() {
        return this.permissions;
    }

    public void setRoleId(String roleId) {
        this.roleId = roleId;
    }

    public void setRoleName(String roleName) {
        this.roleName = roleName;
    }

    public void setRoleIsForbidden(boolean roleIsForbidden) {
        this.roleIsForbidden = roleIsForbidden;
    }

    public void setRoleIsDeleted(boolean roleIsDeleted) {
        this.roleIsDeleted = roleIsDeleted;
    }

    public void setUsers(List<User> users) {
        this.users = users;
    }

    public void setPermissions(List<Permission> permissions) {
        this.permissions = permissions;
    }

    public static class RoleBuilder {
        private String roleId;
        private String roleName;
        private boolean roleIsForbidden;
        private boolean roleIsDeleted;
        private List<User> users;
        private List<Permission> permissions;

        RoleBuilder() {
        }

        public RoleBuilder roleId(String roleId) {
            this.roleId = roleId;
            return this;
        }

        public RoleBuilder roleName(String roleName) {
            this.roleName = roleName;
            return this;
        }

        public RoleBuilder roleIsForbidden(boolean roleIsForbidden) {
            this.roleIsForbidden = roleIsForbidden;
            return this;
        }

        public RoleBuilder roleIsDeleted(boolean roleIsDeleted) {
            this.roleIsDeleted = roleIsDeleted;
            return this;
        }

        public RoleBuilder users(List<User> users) {
            this.users = users;
            return this;
        }

        public RoleBuilder permissions(List<Permission> permissions) {
            this.permissions = permissions;
            return this;
        }

        public Role build() {
            return new Role(roleId, roleName, roleIsForbidden, roleIsDeleted, users, permissions);
        }

        public String toString() {
            return "Role.RoleBuilder(roleId=" + this.roleId + ", roleName=" + this.roleName + ", roleIsForbidden=" + this.roleIsForbidden + ", roleIsDeleted=" + this.roleIsDeleted + ", users=" + this.users + ", permissions=" + this.permissions + ")";
        }
    }
}
